package jaux.tank.admin.modular.system.controller;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Optional;

import javax.annotation.Resource;
import javax.validation.Valid;

import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;

import jaux.tank.admin.core.base.controller.BaseController;
import jaux.tank.admin.core.base.tips.Tip;
import jaux.tank.bean.annotion.core.BussinessLog;
import jaux.tank.bean.annotion.core.Permission;
import jaux.tank.bean.constant.Const;
import jaux.tank.bean.dictmap.RoleDict;
import jaux.tank.bean.dto.RoleDto;
import jaux.tank.bean.entity.system.Role;
import jaux.tank.bean.enumeration.BizExceptionEnum;
import jaux.tank.bean.exception.TankException;
import jaux.tank.bean.vo.node.ZTreeNode;
import jaux.tank.dao.cache.CacheDao;
import jaux.tank.dao.system.RoleRepository;
import jaux.tank.dao.system.UserRepository;
import jaux.tank.service.system.LogObjectHolder;
import jaux.tank.service.system.RoleService;
import jaux.tank.service.system.impl.ConstantFactory;
import jaux.tank.utils.BeanUtil;
import jaux.tank.utils.StringUtils;
import jaux.tank.utils.ToolUtil;
import jaux.tank.warpper.RoleWarpper;

/**
 * 角色控制器
 *
 * @Date 2017年2月12日21:59:14
 */
@Controller
@RequestMapping("/role")
public class RoleController extends BaseController {

    private static final String PREFIX = "/system/role";

    @Resource
    UserRepository userRepository;

    @Resource
    RoleRepository roleRepository;
    @Autowired
    private RoleService roleService;
    
    @Autowired
    CacheDao cacheDao;



    /**
     * 跳转到角色列表页面
     */
    @GetMapping("")
    public String index() {
        return PREFIX + "/role.html";
    }

    /**
     * 跳转到添加角色
     */
    @GetMapping("/role_add")
    public String roleAdd() {
        return PREFIX + "/role_add.html";
    }

    /**
     * 跳转到修改角色
     */
    @Permission
    @GetMapping("/role_edit/{roleId}")
    public String roleEdit(@PathVariable String roleId, Model model) {
        if (ToolUtil.isEmpty(roleId)) {
            throw new TankException(BizExceptionEnum.REQUEST_NULL);
        }
        this.roleRepository.findById(roleId).ifPresent(role->{
        	model.addAttribute(role);
        	model.addAttribute("pName", ConstantFactory.me().getSingleRoleName(role.getPid()));
        	model.addAttribute("deptName", ConstantFactory.me().getDeptName(role.getDeptid()));
        	LogObjectHolder.me().set(role);
        	
        });
        return PREFIX + "/role_edit.html";
    }

    /**
     * 跳转到角色分配
     */
    @Permission
    @GetMapping("/role_assign/{roleId}")
    public String roleAssign(@PathVariable("roleId") String roleId, Model model) {
        if (ToolUtil.isEmpty(roleId)) {
            throw new TankException(BizExceptionEnum.REQUEST_NULL);
        }
        model.addAttribute("roleId", roleId);
        model.addAttribute("roleName", ConstantFactory.me().getSingleRoleName(roleId));
        return PREFIX + "/role_assign.html";
    }

    /**
     * 获取角色列表
     */
    @Permission
    @GetMapping("/list")
    @ResponseBody
    public Object list(@RequestParam(required = false) String roleName) {
        List<Role> roles = null;
        if(StringUtils.isNullOrEmpty(roleName)) {
            roles =  roleRepository.findAll();
        }else{
            roles = roleRepository.findByName(roleName);
        }
        return super.warpObject(new RoleWarpper(BeanUtil.objectsToMaps(roles)));
    }

    /**
     * 角色新增
     */
    @PostMapping("/add")
    @BussinessLog(value = "添加角色", key = "name", dict = RoleDict.class)
    @Permission(Const.ADMIN_NAME)
    @ResponseBody
    public Tip add(@Valid RoleDto role, BindingResult result) {
        if (result.hasErrors()) {
            throw new TankException(BizExceptionEnum.REQUEST_NULL);
        }
        role.setId(null);
        Role roleEntity = new Role();
		BeanUtils.copyProperties(role, roleEntity);
        roleRepository.save(roleEntity);
        return SUCCESS_TIP;
    }

    /**
     * 角色修改
     */
    @PostMapping("/edit")
    @BussinessLog(value = "修改角色", key = "name", dict = RoleDict.class)
    @Permission(Const.ADMIN_NAME)
    @ResponseBody
    public Tip edit(@Valid RoleDto role, BindingResult result) {
        if (result.hasErrors() || StringUtils.isEmpty(role.getId())) {
            throw new TankException(BizExceptionEnum.REQUEST_NULL);
        }
        Role roleEntity = new Role();
		BeanUtils.copyProperties(role, roleEntity);
        roleService.update(roleEntity);
        return SUCCESS_TIP;
    }

    /**
     * 删除角色
     */
    @PostMapping("/remove")
    @BussinessLog(value = "删除角色", key = "roleId", dict = RoleDict.class)
    @Permission(Const.ADMIN_NAME)
    @ResponseBody
    public Tip remove(@RequestParam String roleId) {
        if (ToolUtil.isEmpty(roleId)) {
            throw new TankException(BizExceptionEnum.REQUEST_NULL);
        }

        //不能删除超级管理员角色
        if(roleId.equals(Const.ADMIN_ROLE_ID)){
            throw new TankException(BizExceptionEnum.CANT_DELETE_ADMIN);
        }

        //缓存被删除的角色名称
        LogObjectHolder.me().set(ConstantFactory.me().getSingleRoleName(roleId));

        this.roleService.delRoleById(roleId);

       
        return SUCCESS_TIP;
    }

    /**
     * 查看角色
     */
    @GetMapping("/view/{roleId}")
    @ResponseBody
    public Object view(@PathVariable String roleId) {
        if (ToolUtil.isEmpty(roleId)) {
        	throw new TankException(BizExceptionEnum.REQUEST_NULL);
        }
        Optional<Role> roleOpt = this.roleRepository.findById(roleId);
        if(roleOpt.isPresent()) {
        	return roleOpt.get();
        }else {
        	throw new TankException(BizExceptionEnum.REQUEST_NULL);
        }
    }

    /**
     * 配置权限
     */
    @PostMapping("/setAuthority")
    @BussinessLog(value = "配置权限", key = "roleId,ids", dict = RoleDict.class)
    @Permission(Const.ADMIN_NAME)
    @ResponseBody
    public Tip setAuthority(@RequestParam("roleId") String roleId, @RequestParam("ids") String ids) {
        if (ToolUtil.isOneEmpty(roleId)) {
            throw new TankException(BizExceptionEnum.REQUEST_NULL);
        }
        roleService.setAuthority(roleId, ids);
        return SUCCESS_TIP;
    }

    /**
     * 获取角色列表
     */
    @GetMapping("/roleTreeList")
    @ResponseBody
    public List<ZTreeNode> roleTreeList() {
        List<ZTreeNode> roleTreeList =  roleService.roleTreeList();
        roleTreeList.add(ZTreeNode.createParent());
        return roleTreeList;
    }

    /**
     * 获取角色列表
     */
    @GetMapping("/roleTreeListByUserId/{userId}")
    @ResponseBody
    public List<ZTreeNode> roleTreeListByUserId(@PathVariable String userId) {
    	List<ZTreeNode> roleTreeList = new ArrayList<>();
        this.userRepository.findById(userId).ifPresent(theUser->{
        	
        	String roleid = theUser.getRoleid();
        	if (ToolUtil.isEmpty(roleid) || Arrays.binarySearch(roleid.split(","), Const.ADMIN_ROLE_ID)>-1) {
        		 roleTreeList.addAll(roleService.roleTreeList());
        	} else {
        		String[] roleIds = roleid.split(",");
        		 roleTreeList.addAll(roleService.roleTreeListByRoleId(roleIds));
        	}
        });
        return roleTreeList;
    }

}
